package com.weijian.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weijian.common.enums.GlobalErrorCodeConstants;
import com.weijian.common.exception.ServiceException;
import com.weijian.common.pojo.CommonResult;
import com.weijian.constants.RedisConstants;
import com.weijian.dal.entity.Item;
import com.weijian.mapper.ItemMapper;
import com.weijian.service.CategoryService;
import com.weijian.service.ItemService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.image.ImageModel;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.aop.framework.AopContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 商品表 服务实现类
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements ItemService {

    final StringRedisTemplate stringRedisTemplate;

    final ImageModel imageModel;

    @Override
    public CommonResult<Item> queryItemById(Long id) {
        String itemKey = RedisConstants.CACHE_ITEM_KEY + id;
        String itemJson = stringRedisTemplate.opsForValue().get(itemKey);
        log.info("商品：{}", itemJson);
        if (itemJson != null) {
            return CommonResult.success(JSONUtil.toBean(itemJson, Item.class));
        }
        Item item = getById(id);
        if (item == null) {
            return CommonResult.error(GlobalErrorCodeConstants.NOT_FOUND);
        }
        stringRedisTemplate.opsForValue().set(itemKey, JSONUtil.toJsonStr(item));
        return CommonResult.success(item);
    }

    @Override
    public CommonResult<List<Item>> queryItemByIds(List<Long> ids) {
        List<Item> cachedItems = new ArrayList<>();
        List<Long> missingIds = new ArrayList<>();
        // 1. 先尝试从 Redis 获取商品，并识别缺失的商品 ID
        for (Long id : ids) {
            String itemKey = RedisConstants.CACHE_ITEM_KEY + id;
            String itemJson = stringRedisTemplate.opsForValue().get(itemKey);
            if (itemJson != null) {
                cachedItems.add(JSONUtil.toBean(itemJson, Item.class));
            } else {
                missingIds.add(id);
            }
        }
        log.info("redis获取商品数量：{}", cachedItems.size());
        // 2. 如果 Redis 中已找到全部商品，则直接返回
        if (cachedItems.size() == ids.size()) {
            return CommonResult.success(cachedItems);
        }
        // 3. 查询数据库补全缺失商品
        List<Item> dbItems = listByIds(missingIds);
        if (dbItems.isEmpty()) {
            return CommonResult.error(GlobalErrorCodeConstants.NOT_FOUND);
        }
        // 4. 将数据库查询结果写入 Redis 缓存
        dbItems.forEach(item -> {
            String itemKey = RedisConstants.CACHE_ITEM_KEY + item.getId();
            stringRedisTemplate.opsForValue().set(itemKey, JSONUtil.toJsonStr(item));
        });
        // 5. 合并缓存和数据库数据
        cachedItems.addAll(dbItems);
        return CommonResult.success(cachedItems);
    }

    @Override
    public void updateItem(Item item) {
        if (item.getId() == null) {
            throw new ServiceException(400, "商品为空");
        }
        log.info("更新商品：{}", item);
        updateById(item);
        stringRedisTemplate.delete(RedisConstants.CACHE_ITEM_KEY + item.getId());
    }

    @Override
    public void deleteItemById(Long id) {
        boolean remove = removeById(id);
        if (!remove) {
            throw new ServiceException(400, "删除商品失败");
        }
        stringRedisTemplate.delete(RedisConstants.CACHE_ITEM_KEY + id);
    }

    @Override
    public void deleteItemByIds(List<Long> ids) {
        CategoryService proxy = (CategoryService) AopContext.currentProxy();
        boolean removed = proxy.removeBatchByIds(ids);
        if (!removed) {
            throw new ServiceException(400, "删除商品失败");
        }
        ids.forEach(id -> stringRedisTemplate.delete(RedisConstants.CACHE_ITEM_KEY + id));
    }

    @Override
    public CommonResult<List<Item>> listByCategoryId(Long categoryId) {
        List<Item> itemList = lambdaQuery()
                .eq(Item::getCategoryId, categoryId)
                .list();
        return CommonResult.success(itemList);
    }

    @Override
    public void saveItem(Item item) {
        if (item.getImage() == null || item.getImage().isEmpty()) {
            ImageResponse imageResponse = imageModel.call(new ImagePrompt("根据以下提示词生成图片，用作商家展示"
                    + item.getName() + item.getDescription()));
            String url = imageResponse.getResult().getOutput().getUrl();
            log.info("图片生成成功，图片地址为：{}", url);
            item.setImage(url);
        }
        try {
            save(item);
        } catch (Exception e) {
            log.info("保存菜品失败", e);
            throw new RuntimeException(e);
        }
    }


}
